package com.nike.amoeba

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.KeyEvent
import android.view.Menu
import android.view.View
import android.widget.ExpandableListView
import android.widget.ExpandableListView.CHOICE_MODE_MULTIPLE
import android.widget.ExpandableListView.CHOICE_MODE_SINGLE
import android.widget.ExpandableListView.OnGroupClickListener
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.GravityCompat
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.lifecycle.viewModelScope
import androidx.navigation.Navigation
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.StringUtils
import com.blankj.utilcode.util.ToastUtils
import com.nike.amoeba.adapter.MainDrawerExpandableAdapter
import com.nike.amoeba.api.UIHelper
import com.nike.amoeba.base.BaseActivity
import com.nike.amoeba.bean.DataBean
import com.nike.amoeba.bean.RfidStateBean
import com.nike.amoeba.databinding.AMainBinding
import com.nike.amoeba.ext.RFID_TAG
import com.nike.amoeba.ext.SCAN_STATUS_SCAN
import com.nike.amoeba.ext.showMessage
import com.nike.amoeba.keyctrl.Common
import com.nike.amoeba.keyctrl.ScanThread
import com.nike.amoeba.keyctrl.ScanType
import com.nike.amoeba.keyctrl.ThreadPoolManager
import com.nike.amoeba.keyctrl.entity.TagFindParam
import com.nike.amoeba.mar.eventViewModel
import com.nike.amoeba.util.CacheUtil
import com.nike.amoeba.util.MusicUtils
import com.nike.amoeba.viewmodel.AssetModel
import com.nike.amoeba.viewmodel.AssetSearchmModel
import com.nike.amoeba.viewmodel.RfidModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import rfid.uhfapi_y2007.core.Util
import rfid.uhfapi_y2007.entities.MemoryBank
import rfid.uhfapi_y2007.entities.TagParameter
import rfid.uhfapi_y2007.protocol.vrp.MsgPowerOff
import rfid.uhfapi_y2007.protocol.vrp.MsgTagInventory
import java.util.Date


class MainActivity : BaseActivity<RfidModel, AMainBinding>(),  OnGroupClickListener,
    ExpandableListView.OnChildClickListener {

    lateinit var appBarConfiguration: AppBarConfiguration

    val assetModel: AssetModel by viewModels()

    val assetSearchmModel: AssetSearchmModel by viewModels()

    var scanThread: ScanThread? = null

    val listBean: ArrayList<DataBean> by lazy {ArrayList()}

    val adapter: MainDrawerExpandableAdapter by lazy { MainDrawerExpandableAdapter(this, listBean) }

    override fun initView(savedInstanceState: Bundle?) {
//        KeyRecerver.setKeyRecvCallback(this)
        val tvTitle = mDatabind.navHeaderMain.findViewById<AppCompatTextView>(R.id.tv_title)
        val user = CacheUtil.getUser()
        tvTitle.text = "：" + user?.LoginID

        //初始化二级列表
        mViewModel.viewModelScope.launch(Dispatchers.IO) {
            mViewModel.mainDrawerParentDao.findAll().forEach {
                val bean = DataBean(Title = it.Name, Type = it.Type)
                if (bean.Type <= 2){
                    val childAll = mViewModel.mainDrawerParentDao.findChildAll(bean.Type, mViewModel.userId, mViewModel.companyId)
                    if (childAll.size != 0){
                        childAll.forEach {
                            bean.ExpandableChild.add(DataBean(Title = it.Name, Code = it.Code, Type = it.Type))
                        }
                    }else{
                        bean.Status = -1
                        bean.ExpandableChild.add(DataBean(Title = getString(R.string.no_data)))
                    }
                }
                listBean.add(bean)
            }
            mDatabind.expandableListView.setAdapter(adapter)
        }
        mDatabind.expandableListView.setOnGroupClickListener(this)
        mDatabind.expandableListView.setOnChildClickListener(this)

        mDatabind.expandableListView.setOnGroupExpandListener { groupPosition ->
            for (i in 0 until adapter.groupCount) {
                if (i != groupPosition) {
                    mDatabind.expandableListView.collapseGroup(i)
                }
            }
        }

        //注册广播接收
        registerReceiver()
        lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onPause(owner: LifecycleOwner) {
                super.onPause(owner)
                mViewModel.isOpen.value = false
            }

            override fun onStop(owner: LifecycleOwner) {
                super.onStop(owner)
                if (!AppUtils.isAppForeground()) {
                    //app 进入后台
                    mViewModel.isActive.set(false) //记录当前已经进入后台
                    mViewModel.isOpen.value = false
                }
            }

            override fun onDestroy(owner: LifecycleOwner) {
                super.onDestroy(owner)
                unregisterReceiver(keyReceiver)

                mViewModel.mIsContinuous.set(false)
                if (scanThread != null) {
                    scanThread!!.stopScan()
                    scanThread!!.interrupt()
                    scanThread!!.close()
                    scanThread = null
                }
            }
        })

        //实现右边drawlayout
        mDatabind.appBarMain.includeToolbar.toolbar.run {
            setOnMenuItemClickListener {
                when (it.itemId) {
                    R.id.home_set -> {
                        mDatabind.drawerLayout.openDrawer(GravityCompat.START)
                    }
                }
                true
            }
        }
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        setSupportActionBar(mDatabind.appBarMain.includeToolbar.toolbar)
        val navController = findNavController(R.id.nav_host_fragment_content_main)
        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.takeAssetFrg,
                R.id.taskStockFrg,
                R.id.stockManageParentFrg,
                R.id.stockAdjustFrg,
                R.id.downloadFrg,
                R.id.uploadFrg,
                R.id.configFrg,
//                R.id.nav_login
            ), mDatabind.drawerLayout
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        mDatabind.navView.setupWithNavController(navController)

        scanThread = try {
            ScanThread(mHandler)
        } catch (e: Exception) {
            // 出现异常
            Toast.makeText(applicationContext, "serialport init fail", Toast.LENGTH_SHORT).show()
            return
            // e.printStackTrace();
        }
        scanThread?.start()
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
//        menuInflater.inflate(R.menu.home_menu, menu)
//        findViewById<NavigationView>(R.id.nav_view).setCheckedItem(R.id.nav_asset)
        return true
    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = findNavController(R.id.nav_host_fragment_content_main)
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }

    override fun createObserver() {
        super.createObserver()
        // rfid数据接收回调
        mViewModel.rfidData.observe(this, {
            mViewModel.mTotalCount += 1
            var tagId = mViewModel.rfidData.value!!.TagId
            if (tagId.contains(" ")) {
                tagId = tagId.replace(" ", "")
            }
            LogUtils.e(tagId, it.Rssi)
            //搜索/识别回调
            if (mViewModel.tagFindParam == null) {
                assetModel.epcData.value = RfidStateBean(
                    tagId = tagId,
                    scanStatus = SCAN_STATUS_SCAN,
                    rssi = it.Rssi
                )
                mViewModel.rfidDataCallback.value = RfidStateBean(
                    tagId = tagId,
                    scanStatus = SCAN_STATUS_SCAN,
                    rssi = it.Rssi
                )
            } else {
                assetSearchmModel.epcData.value = RfidStateBean(
                    tagId = tagId,
                    rssi = it.Rssi
                )
            }
        })

        //是否启动rdif
        mViewModel.isOpen.observe(this, { resultState ->
            if (resultState && mViewModel.initConn.get()) {
                mViewModel.onClean()
                mViewModel.startStat()
                if (Common.reader != null && Common.reader.isConnected) {
                    Common.reader.Send(MsgPowerOff()) // 先停止

                    //EPC
                    Common.selectEpcParam = TagParameter()
                    Common.scanType = ScanType.ScanEpc
                    Common.reader.Send(MsgTagInventory())
                    Common.selectEpcParam.MemoryBank = MemoryBank.EPCMemory

                    //TID
//                    Common.selectParam = TagParameter()
//                    Common.scanType = ScanType.ScanTid
//                    Common.reader.Send(MsgTagRead())
//                    Common.selectParam.MemoryBank = MemoryBank.TIDMemory

                    if (Common.isEnableBeep) ThreadPoolManager.getInstance()
                        .execute(mViewModel.threadBeep) // 蜂鸣线程
                    mViewModel.isScan.set(true)
                } else {
                    showMessage(message = "Connection failed")
                }
            } else {
                if (mViewModel.isScan.get()) {
                    mViewModel.isScan.set(false)
                    mViewModel.onClean()
                    mViewModel.disconn()
//                mViewModel.initStop()
                    mViewModel.stopStat()
                    LogUtils.e("读卡断开")
                }
            }
        })

        //指定搜索RFID
        mViewModel.isSearchOpen.observe(this, {
            if (StringUtils.isEmpty(it)) {
                mViewModel.tagFindParam = null
                mViewModel.isOpen.value = false
            } else {
                mViewModel.tagFindParam = TagFindParam()
                mViewModel.tagFindParam?.ScanMB = RFID_TAG
                mViewModel.tagFindParam?.Data = Util.ConvertHexStringToByteArray(it)
                mViewModel.tagFindParam?.Mask = Util.ConvertHexStringToByteArray(it)
                mViewModel.isOpen.value = true
            }
        })

        MusicUtils.init(this)
        eventViewModel.playMusic.observeInActivity(this, Observer {
            if (it){
                MusicUtils.play()
            }else{
                MusicUtils.stop()
            }
        })

        eventViewModel.mainDrawerUploadEvent.observeInActivity(this, Observer {
            mViewModel.viewModelScope.launch(Dispatchers.IO) {
                listBean.forEachIndexed { index, bean ->
                    if (bean.Type <= 2){
                        val childAll = mViewModel.mainDrawerParentDao.findChildAll(bean.Type, mViewModel.userId, mViewModel.companyId)
                        if (childAll.size != 0){
                            bean.Status = 0
                            bean.ExpandableChild.clear()
                            childAll.forEach {
                                val child = bean.ExpandableChild
                                child.add(DataBean(Title = it.Name, Code = it.Code, Type = it.Type))
                            }
                        }
                    }else{
                        return@forEachIndexed
                    }
                }
                withContext(Dispatchers.Main) {
                    adapter.notifyDataSetChanged()
                }
            }
        })
    }

    private var keyReceiver: KeyReceiver? = null
    fun registerReceiver() {
        keyReceiver = KeyReceiver()
        val filter = IntentFilter()
        filter.addAction("android.rfid.FUN_KEY")
        filter.addAction("android.intent.action.FUN_KEY")
        registerReceiver(keyReceiver, filter)
    }

    override fun onDestroy() {
        super.onDestroy()
        setSupportActionBar(null)
    }

    //region 模组点击跳转事件
    override fun onGroupClick(parent: ExpandableListView?, v: View?, groupPosition: Int, id: Long): Boolean {
        val navController = findNavController(R.id.nav_host_fragment_content_main)
        when(groupPosition){
            3 -> UIHelper.startDownloadFrg(navController)
            4 -> UIHelper.starUploadFrg(navController)
            5 -> UIHelper.starRfidConfigFrg(navController)
            6 ->{
                val user = CacheUtil.getUser()
                if (!user!!.isRememberPwd){
                    CacheUtil.setUser(null)
                }else{
                    user?.Password = ""
                    CacheUtil.setUser(user)
                }
                UIHelper.startLoginAct()
                ActivityUtils.finishAllActivities()
            } else ->{

            }
        }
        if (groupPosition > 2){
            mDatabind.drawerLayout.closeDrawers()
        }

        listBean.forEach { it.isSelect = false }
        listBean.forEach {
            it.ExpandableChild.forEach { it.isSelect = false }
        }
        val bean = listBean.get(groupPosition)
        bean.isSelect = true
        adapter.notifyDataSetChanged()

        val groupExpanded = mDatabind.expandableListView.isGroupExpanded(groupPosition)
        if (!groupExpanded){
            mDatabind.expandableListView.expandGroup(groupPosition)
        }
        return true
    }

    override fun onChildClick(
        parent: ExpandableListView?,
        v: View?,
        groupPosition: Int,
        childPosition: Int,
        id: Long
    ): Boolean {
        val navController = findNavController(R.id.nav_host_fragment_content_main)
        val parentBean = listBean[groupPosition]
        if (parentBean.Status == -1)return true
        val bean = listBean[groupPosition].ExpandableChild.get(childPosition)
        val code = bean.Code
        val title = bean.Title
        //盘点管理
        if (parentBean.Type == 0){
            if (bean.Type == 0){
                UIHelper.startTaskAssetFrg(navController, code, title)
                eventViewModel.assetListUploadEvent.value = bean
            }else{
                UIHelper.startTaskStockFrg(navController, code, title)
                eventViewModel.stockListUploadEvent.value = bean
            }
        }else if (parentBean.Type == 1){
            UIHelper.starStockManageParentFrg(navController, code, title)
            eventViewModel.stockManageUploadEvent.value = bean
        }else if (parentBean.Type == 2){
            UIHelper.starStockAdjustFrg(navController, code, title)
            eventViewModel.stockAdjustUploadEvent.value = bean
        }
        if (bean.Type != -1){
            mDatabind.drawerLayout.closeDrawers()
        }
        listBean.forEach { it.isSelect = false }
//        parentBean.isSelect = true
        parentBean.ExpandableChild.forEach { it.isSelect = false }
        bean.isSelect = true
        adapter.notifyDataSetChanged()
        return false
    }
    //endregion

    //region 按键广播

    private inner class KeyReceiver : BroadcastReceiver() {

        var clickTime: Date? = null

        override fun onReceive(context: Context, intent: Intent) {
            var keyCode = intent.getIntExtra("keyCode", 0)
            if (keyCode == 0) {
                keyCode = intent.getIntExtra("keycode", 0)
            }
            if (keyCode != KeyEvent.KEYCODE_F4) return
            val keyDown = intent.getBooleanExtra("keydown", true)
            if (keyDown) {
                if (clickTime != null) {
                    val t = Date().time - clickTime!!.time
                    if (t < 1000) return
                }
                clickTime = Date()
            } else {
                scanThread!!.scan()
            }
        }
    }

    var exitTime = 0L
    override fun onBackPressed() {
        if (mDatabind.drawerLayout.isDrawerOpen(GravityCompat.END)) {
            mDatabind.drawerLayout.closeDrawers()
        } else {
            val nav = Navigation.findNavController(this@MainActivity, R.id.nav_host_fragment_content_main)
            val currentDestinationId = nav.currentDestination?.id
            if (currentDestinationId != null && !appBarConfiguration.topLevelDestinations.contains(currentDestinationId)) {
                nav.navigateUp()
            } else {
                if (System.currentTimeMillis() - exitTime > 2000) {
                    ToastUtils.showShort("再按一次退出程序")
                    exitTime = System.currentTimeMillis()
                } else {
                    finish()
                }
            }
        }
    }

    private val mHandler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            if (msg.what == ScanThread.SCAN) {
                mViewModel.mIsPressed.set(false)
                val dataBytes = msg.data.getByteArray("dataBytes")
                if (dataBytes == null || dataBytes.size == 0) {
                    if (mViewModel.mIsContinuous.get()) {
                        scanThread?.scan()
                    }
                    return
                }
                var data = ""
                /*if (false) {  GBK格式
                    try {
                        data = String(dataBytes, 0, dataBytes.size, "GBK")
                    } catch (e: UnsupportedEncodingException) {
                        e.printStackTrace()
                    }
                } else {
                    data = String(dataBytes, 0, dataBytes.size)
                }*/
                data = String(dataBytes, 0, dataBytes.size)
                if (data == null || data == "") {
                    if (mViewModel.mIsContinuous.get()) {
                        scanThread?.scan()
                    }
                    return
                }
                if (data.contains("\r")){
                    data = data.replace("\r", "")
                }
                mViewModel.scanData.value = data
                mViewModel.scanDataCallback.value = data
                LogUtils.e(data)
                if (mViewModel.mIsContinuous.get()) {
                    scanThread?.scan()
                }
            }
        }
    }
}

